#include "adc.h"
#include "SysTick.h"

ADC_HandleTypeDef ADC1_Handler;								// ADC句柄

/***************************
* 函数名： ADCx_Init
* 功能：ADC初始化函数
* 输入：无
* 输出：无
*/
void ADCx_Init(void)
{
	RCC_PeriphCLKInitTypeDef ADC_CLKInit;
	
	ADC_CLKInit.PeriphClockSelection=RCC_PERIPHCLK_ADC;					// ADC外设时钟
	ADC_CLKInit.AdcClockSelection=RCC_ADCPCLK2_DIV6;						// 分频因子6时钟为72M/6=12MHz
	HAL_RCCEx_PeriphCLKConfig(&ADC_CLKInit);										// 设置ADC时钟
	
	ADC1_Handler.Instance=ADC1;
	ADC1_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT;						// 右对齐
	ADC1_Handler.Init.ScanConvMode=DISABLE;											// 非扫描模式
	ADC1_Handler.Init.ContinuousConvMode=DISABLE;								// 关闭连续转换
	ADC1_Handler.Init.NbrOfConversion=1;												// 1个转换在规则顺序中，即只转换规则序列1
	ADC1_Handler.Init.DiscontinuousConvMode=DISABLE;						// 禁止不连续采样模式
	ADC1_Handler.Init.NbrOfDiscConversion=0;										// 不连续采样通道数为0
	ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START;			// 软件触发
	HAL_ADC_Init(&ADC1_Handler);																// 初始化
	
	HAL_ADCEx_Calibration_Start(&ADC1_Handler);									// 校准ADC
}

/*********************************************
* ADC底层驱动，引脚配置，时钟使能
* 该函数被HAL_ADC_Init()调用
* hadc：ADC句柄
*********************************************/
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	__HAL_RCC_ADC1_CLK_ENABLE();						// 使能ADC1时钟
	__HAL_RCC_GPIOA_CLK_ENABLE();						// 使能GPIOA时钟
	
	
	GPIO_InitStructure.Pin=GPIO_PIN_1;				// PA1
	GPIO_InitStructure.Mode=GPIO_MODE_ANALOG;	// 模拟
	GPIO_InitStructure.Pull=GPIO_NOPULL;			// 不带上下拉
	HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);
}

/*********************************************************
* 获得ADC值
* ch：通道值0~16，取值范围：ADC_CHANNEL_0~ADC_CHANNEL_16
* 返回：转换结果
**********************************************************/
u16 Get_Adc(u32 ch)
{
	ADC_ChannelConfTypeDef ADC1_ChanConf;
	
	ADC1_ChanConf.Channel=ch;															// 通道
	ADC1_ChanConf.Rank=1;																	// 第1个序列，序列1
	ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_239CYCLES_5;// 采样时间
	HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);	// 通道配置
	
	HAL_ADC_Start(&ADC1_Handler);													// 开启ADC
	HAL_ADC_PollForConversion(&ADC1_Handler,10);					// 轮询转换
	
	return (u16)HAL_ADC_GetValue(&ADC1_Handler);					// 返回最近一次ADC1规则组转换结果
}

/***************************************************
* 获取指定通道转换值，取times次，平均
* times：获取次数
* 返回：通道ch的times次转换结果的平均值，ADC1最大值为12位
***************************************************/
u16 Get_ADC_Value(u32 ch,u8 times)
{
	u32 temp_val=0;
	u8 t;
	for(t=0;t<times;t++)
	{
		temp_val += Get_Adc(ch);
		delay_ms(5);
	}
	return temp_val/times;
}